/**
 * @(#)com.tansun.easycare.rule.excel.web.ExcelAction.java Copyright (c) 2017 天阳宏业科技股份有限公司
 */
package com.tansun.easycare.rule.excel.web;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tansun.easycare.rule.common.enums.RuleModelTypeFileEnum;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.tansun.easycare.rule.common.RuleBaseController;
import com.tansun.easycare.rule.common.model.Bom;
import com.tansun.easycare.rule.common.model.Domain;
import com.tansun.easycare.rule.common.model.ResponseVO;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.common.service.SpringInstanceUtils;
import com.tansun.easycare.rule.datamodel.service.impl.ModelImpoter;
import com.tansun.easycare.rule.decisiontree.entity.DecisionTreeEntity;
import com.tansun.easycare.rule.decisiontree.model.DecisionSubNode;
import com.tansun.easycare.rule.decisiontree.model.RuleTreeManageVO;
import com.tansun.easycare.rule.decisiontree.service.DecisionTreeService;
import com.tansun.easycare.rule.excel.entity.decision.DecisionExcelEntity;
import com.tansun.easycare.rule.excel.handle.BaseHandle;
import com.tansun.easycare.rule.excel.handle.impl.DecisionTableHandle;
import com.tansun.easycare.rule.excel.handle.impl.EvaluationIndexHandle;
import com.tansun.easycare.rule.excel.handle.impl.GeneralRuleHandle;
import com.tansun.easycare.rule.excel.handle.impl.RuleSetHandle;
import com.tansun.easycare.rule.excel.handle.impl.SingleTbIndexHandle;
import com.tansun.easycare.rule.excel.service.DecisionTableExcelService;
import com.tansun.easycare.rule.excel.service.EvaluationIndexExcelService;
import com.tansun.easycare.rule.excel.service.SingleTbIndexExcelService;
import com.tansun.easycare.rule.excel.utils.ExcelErrorMsg;
import com.tansun.easycare.rule.policytree.model.PolicyTreeModel;
import com.tansun.easycare.rule.policytree.service.PolicyTreeService;
import com.tansun.easycare.rule.rulegroup.entity.RuleEntry;
import com.tansun.easycare.rule.rulegroup.entity.RuleGroup;
import com.tansun.easycare.rule.rulegroup.model.RuleGroupVO;
import com.tansun.easycare.rule.rulegroup.service.RuleEntryService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupRefService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.scoremodel.model.ScoreEntity;
import com.tansun.easycare.rule.scoremodel.model.ScoreItem;
import com.tansun.easycare.rule.scoremodel.service.ScoreModelService;
import com.tansun.easycare.rule.table.exclusions.entity.ExclusionsBO;
import com.tansun.easycare.rule.table.exclusions.service.ExclusionsService;
import com.tansun.easycare.rule.utils.ExcelConstant;
import com.tansun.easycare.rule.utils.ExcelDownloadUtils;
import com.tansun.easycare.rule.utils.ExcelUtils;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.StringUtils;

/**
 *
 * @author zengdong
 * @version 1.0  2017年5月22日
 * @modified zengdong  2017年5月22日  <创建>
 */
@RestController
@RequestMapping(value = "/ruleProj/excel")
public class ExcelAction extends RuleBaseController {
    @Autowired
    private RuleManageService ruleManageService;
    @Autowired
    private ScoreModelService scoreModelService;
    @Autowired
    private DecisionTreeService decisionTreeService;
    @Autowired
    private DecisionTableExcelService decisionTableExcelService;

    @Autowired
    private EvaluationIndexExcelService evaluationIndexExcelService;

    @Autowired
    private SingleTbIndexExcelService singleTbIndexExcelService;
    @Autowired
    private ExclusionsService exclusionsService;
    @Autowired
    private DataBomService dataBomService;
    @Autowired
    private PolicyTreeService policyTreeService;
    @Autowired
    private ModelImpoter modelImporter;
    @Autowired
    private RuleGroupService ruleGroupService;
    @Autowired
    private RuleGroupRefService ruleGroupRefService;
    @Autowired
    private RuleEntryService ruleEntryService;

    
    @RequestMapping(value="/downloadTemplate{downloadType:.*}",method=RequestMethod.POST)
    public void exportExcelTemplate(@PathVariable String downloadType, HttpServletResponse res,
                            HttpServletRequest req,@RequestParam("type") String  type) throws Exception {
        OutputStream os = res.getOutputStream();
        res.setContentType("application/octet-stream; charset=utf-8");
        String userAgent = req.getHeader("User-Agent");
        if (userAgent == null)
            userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
        try {
        	String   fileName ="";
        	if ("singletblindex".equals(type.toLowerCase())) {
        		 fileName ="singleTblIndex.xlsx";
        	}else if("scoremodel".equals(type.toLowerCase())) {
        		fileName ="scoreModel.xlsx";
        	}else if("decisiontree".equals(type.toLowerCase())){
        		fileName = "decisionTree.xlsx";
        	}  
        	if (fileName.equals("")) {
        		return ;
        	}
            InputStream in = SpringInstanceUtils.instance.getResource("classpath:ImportTemplate/"+fileName).getInputStream();
            fileName = userAgent.contains("MSIE") ? URLEncoder.encode(fileName, "UTF-8") : new String(fileName.getBytes(), "ISO8859-1");
            res.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            IOUtils.copy(in, os);
            os.flush();
        }catch(Exception e) {
        	e.printStackTrace();
        }finally {
            if (os != null) {
                os.close();
            }
        }       
    
    } 	
    
    @RequestMapping(value="/download{downloadType:.*}",method=RequestMethod.POST)
    public void exportExcel(@PathVariable String downloadType, HttpServletResponse res,
                            HttpServletRequest req, @RequestParam("projectCode") String projectCode, @RequestParam("id") String id,String datamodelid,String rankRelationId) throws Exception {
        OutputStream os = res.getOutputStream();
       
        res.setContentType("application/octet-stream; charset=utf-8");
        String filename = ExcelConstant.RULE_DATASET_IMPORT_FILENAME;
        String type = req.getParameter("type");
        res.setHeader("Content-Disposition", "attachment; filename=" + filename);
        String userAgent = req.getHeader("User-Agent");
        if (userAgent == null)
            userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
        Workbook wb = null;
        try {
           
            Map<String, Domain> attrMap = dataBomService.findDomainByProjectCode(projectCode);
            Map<String, Bom> metaMap = dataBomService.findBomMapByProjectCode(projectCode,null);
            if("dataset".equals(type.toLowerCase())){
                filename = "数据模型.xls";
                wb = modelImporter.download(null, projectCode,datamodelid,rankRelationId);
            }else if("decisiontable".equals(type.toLowerCase())){
                filename = "决策表.xlsx";
                if (StringUtils.isNotBlank(id)) {
                    //获取导出实体
                    List<DecisionExcelEntity> decisiontableDetails = decisionTableExcelService.getDetailByManageId(id);
                    if (decisiontableDetails != null && decisiontableDetails.size() > 0) {
                        BaseHandle<DecisionExcelEntity> handle = new DecisionTableHandle();
                        wb = handle.entityToExcel(decisiontableDetails);
                    }
                }
            }else if("evaluationindex".equals(type.toLowerCase())){
                filename = "赋值索引.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    //获取导出实体
                    List<DecisionExcelEntity> evaluationIndexDetails = evaluationIndexExcelService.getDetailByManageId(id);
                    if (evaluationIndexDetails != null && evaluationIndexDetails.size() > 0) {
                        BaseHandle<DecisionExcelEntity> handle = new EvaluationIndexHandle();
                        wb = handle.entityToExcel(evaluationIndexDetails);
                    }
                }
            }else if("singletblindex".equals(type.toLowerCase())){
                filename = "一维表索引.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    //获取导出实体
                    List<DecisionExcelEntity> singleTbIndexDetails = singleTbIndexExcelService.getDetailByManageId(id);
                    if (singleTbIndexDetails != null && singleTbIndexDetails.size() > 0) {
                        BaseHandle<DecisionExcelEntity> handle = new SingleTbIndexHandle();
                        wb = handle.entityToExcel(singleTbIndexDetails);
                    }
                }
            }else if("exclusions".equals(type.toLowerCase())){
                filename = "排除项.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    ExcelDownloadUtils util = new ExcelDownloadUtils(attrMap, metaMap);
                    //1.获取评分模型信息
                    RuleManage exclusion = ruleManageService.getById(id);
                    List<ExclusionsBO> exclusionItemList = exclusionsService.findExclusionItemByIndexId(exclusion.getId(), exclusion.getVersion());
                    wb = util.downloadExclusion(exclusion, exclusionItemList);
                }
            }else if("scoremodel".equals(type.toLowerCase())){
                filename = "评分模型.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    ExcelDownloadUtils util = new ExcelDownloadUtils(attrMap, metaMap);
                    //1.获取评分模型信息
                    RuleManage scoreModel = ruleManageService.getById(id);
                    List<ScoreItem> scoreItemList = scoreModelService.getScoreItems(id, scoreModel.getVersion());

                    wb = util.downloadScore(scoreModel, scoreItemList);
                }
            }else if("decisiontree".equals(type.toLowerCase())){
                filename = "决策树.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    ExcelDownloadUtils util = new ExcelDownloadUtils(attrMap, metaMap);
                    //1.获取评分模型信息
                    RuleManage tree = ruleManageService.getById(id);
                    RuleTreeManageVO ruleTree= decisionTreeService.getTreeInfo(tree.getId(), tree.getVersion(),null,null);
                    List<DecisionSubNode> scoreItemList = ruleTree.getNodeList();

                    wb = util.downloadTree(tree, scoreItemList);
                }
            }else if("policytree".equals(type.toLowerCase())){
                filename = "策略树.xlsx";
                if (StringUtils.isNoneBlank(id)) {
                    RuleManage scoreModel = ruleManageService.getById(id);
                    ExcelDownloadUtils util = new ExcelDownloadUtils(attrMap, metaMap);
                    PolicyTreeModel entity = policyTreeService.findPolicyTreeModel(scoreModel.getCode(), scoreModel.getVersion(), scoreModel.getProjectCode());
                    wb = util.downloadPolicyTree(entity);
                }
            }else if("generalrule".equals(type.toLowerCase())){
                filename = "规则.xlsx";
                BaseHandle<RuleGroup> handle = new GeneralRuleHandle();
                //根据id获取到实体
                RuleGroup group = new RuleGroup();
                List<RuleGroup> list = new ArrayList<RuleGroup>();
                if(StringUtils.isNotEmpty(id)) {
	                for(String theId :id.split(",")) {
	                	RuleManage rm = ruleManageService.getById(theId);
	                	group.setManageId(theId);
	                	group.setVersion(rm.getVersion());
	                    list.addAll(ruleGroupService.findList(group));
	                }
                }
                if(list!=null&&list.size()>0){
                    wb = handle.entityToExcel(list);
                }
            }else if("policyrulegroup".equals(type.toLowerCase())){
                filename = "规则集.xlsx";
                
                List<RuleGroupVO> ruleGroupVos = new ArrayList<>();
                RuleGroupVO ruleGroupVo = creteGroupVo(id);
                ruleGroupVos.add(ruleGroupVo);
                BaseHandle<RuleGroupVO> handle = new RuleSetHandle();
                wb = handle.entityToExcel(ruleGroupVos);
            }
            filename = userAgent.contains("MSIE") ? URLEncoder.encode(filename, "UTF-8") : new String(filename.getBytes(), "ISO8859-1");
            res.setHeader("Content-Disposition", "attachment; filename=" + filename);
            wb.write(os);
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        	if (wb != null) {
        		wb.close();
        	}
            if (os != null) {
                os.close();
            }
        }
    }

    /**
     * 导入excel
     * @param file
     * @param uploadType
     * @param request
     * @param res
     * @param projectCode
     * @param modelName
     * @param isImportUser
     * @throws Exception
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseVO importExcel(@RequestParam("file") MultipartFile file,HttpServletRequest request, HttpServletResponse res, @RequestParam("projectCode") String projectCode,String datamodelid, String userId,String rankRelationId) throws Exception {
     	ResponseVO msg = new ResponseVO();
        String type = request.getParameter("type");
        String fileName = file.getOriginalFilename();
        try {
            Workbook workbook = null;
            // 判断上传文件类型
            if (file.getOriginalFilename().toLowerCase().endsWith("xlsx")) {
                workbook = new XSSFWorkbook(file.getInputStream());
            } else if (file.getOriginalFilename().toLowerCase().endsWith("xls")) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else {
            	msg.setDescription("failure\", \"文件不是Excel格式");
                msg.setStatus(ResponseVO.ERROR);
            }
            ExcelErrorMsg errmsg = null;
            if (workbook != null) {
                Map<String, Domain> attrMap = dataBomService.findDomainByProjectCode(projectCode);
                Map<String, Bom> metaMap = dataBomService.findBomMapByProjectCode(projectCode,null);
                ExcelUtils util = new ExcelUtils(attrMap, metaMap);
                if("dataset".equals(type.toLowerCase())){
                    modelImporter.upload(file,projectCode, datamodelid, userId, rankRelationId);
                }else if("decisiontable".equals(type.toLowerCase())){
                    BaseHandle<DecisionExcelEntity> decisionTableHandle = new DecisionTableHandle();
                    //从Excel里获取导入对象
                    List<DecisionExcelEntity> decisionTableList = decisionTableHandle.excelToEntity(workbook, projectCode,userId);
                    //数据校验
                    errmsg = decisionTableExcelService.verifyDecisionTable(decisionTableList);
                    if (errmsg.isExistsErrorMsg()) {
                        throw new IllegalStateException(errmsg.toString());
                    } else {
                        DecisionExcelEntity entity = decisionTableList.get(0);
                        String[] arr = fileName.split("_");
                        if (arr.length == 3) {
                            entity.setCode(arr[0]);
                            entity.setVersion(arr[1]);
                        }
                        //保存至数据库
                        decisionTableExcelService.saveExcelInfoToDb(decisionTableList,rankRelationId);
                    }
                }else if("evaluationindex".equals(type.toLowerCase())){
                    BaseHandle<DecisionExcelEntity> evaluationIndexHandle = new EvaluationIndexHandle();
                    //从Excel里获取导入对象
                    List<DecisionExcelEntity> evaluationIndexList = evaluationIndexHandle.excelToEntity(workbook, projectCode,userId);
                    //数据校验
                    errmsg = evaluationIndexExcelService.verifyDecisionTable(evaluationIndexList);
                    if (errmsg.isExistsErrorMsg()) {
                        throw new IllegalStateException(errmsg.toString());
                    } else {
                        DecisionExcelEntity entity = evaluationIndexList.get(0);
                        String[] arr = fileName.split("_");
                        if (arr.length == 3) {
                            entity.setCode(arr[0]);
                            entity.setVersion(arr[1]);
                        }
                        //保存至数据库
                        evaluationIndexExcelService.saveExcelInfoToDb(evaluationIndexList,rankRelationId);
                    }
                }else if("singletblindex".equals(type.toLowerCase())){
                    BaseHandle<DecisionExcelEntity> singleTbIndexHandle = new SingleTbIndexHandle();
                    //从Excel里获取导入对象
                    List<DecisionExcelEntity> singleTbIndexList = singleTbIndexHandle.excelToEntity(workbook, projectCode,userId);
                    //数据校验
                    errmsg = singleTbIndexExcelService.verifyDecisionTable(singleTbIndexList);
                    if (errmsg.isExistsErrorMsg()) {
                        throw new IllegalStateException(errmsg.toString());
                    } else {
                        DecisionExcelEntity entity = singleTbIndexList.get(0);
                        String[] arr = fileName.split("_");
                        if (arr.length == 3) {
                            entity.setCode(arr[0]);
                            entity.setVersion(arr[1]);
                        }
                        RuleManage ruleManage=new RuleManage();
                        ruleManage.setRankRelationId(rankRelationId);
                        ruleManage.setName(entity.getName());
//                        Integer num = this.ruleManageService.countListFindName(ruleManage, RuleModelTypeFileEnum.SingleTblIndex.type);
//                        if (num != null && num>0) {
//                            msg.setStatus(ResponseVO.ERROR);
//                            msg.setDescription("该名称已存在，请修改名称后，重新上传");
//                            return msg;
//                        }
                        //保存至数据库
                        singleTbIndexExcelService.saveExcelInfoToDb(singleTbIndexList,rankRelationId);
                    }
                }else if("exclusions".equals(type.toLowerCase())){
                    exclusionsService.saveOrUpdate(util.parseExclusion(file, projectCode));
                }else if("scoremodel".equals(type.toLowerCase())){
                	ScoreEntity scoreEntity = util.parseScoreModel(file, projectCode, rankRelationId);
                	ruleManageService.checkImport(scoreEntity.getScoreModel(), RuleModelTypeEnum.ScoreModel.getCode());
                    scoreModelService.saveOrUpdate(scoreEntity);
                }else if("decisiontree".equals(type.toLowerCase())){
                    DecisionTreeEntity entity = util.parseDecisionTree(file, projectCode,rankRelationId);
                    ruleManageService.checkImport(entity.getRuleManage(), RuleModelTypeEnum.DecisionTree.getCode());
                    decisionTreeService.saveOrUpdateDecisionTree(entity.getRuleManage());
                    decisionTreeService.saveOrUpdate(entity);
                }else if("policytree".equals(type.toLowerCase())){
                    policyTreeService.saveOrUpdate(util.parsePolicyTree(file, projectCode,rankRelationId));
                }

               
            } else {
               msg.setStatus(ResponseVO.ERROR);
            }
        } catch (Exception e) {
        	e.printStackTrace();
        	 msg.setStatus(ResponseVO.ERROR);
             msg.setDescription(e.getMessage());
        }
        return  msg;

    }

    public RuleGroupVO creteGroupVo(String manageId){
    	
    	RuleManage ruleManage = this.ruleManageService.get(manageId);
    	String orgVersion = ruleManage.getVersion();
    	
        RuleEntry ruleEntry = new RuleEntry();
        ruleEntry.setManageId(manageId);
        ruleEntry.setVersion(ruleManage.getVersion());
        List<RuleEntry> ruleEntryList = this.ruleEntryService.findList(ruleEntry);
        
        RuleGroup groupInfo = new RuleGroup();
        groupInfo.setManageId(manageId);
        groupInfo.setVersion(ruleManage.getVersion());
        List<RuleGroup> insertList = this.ruleGroupRefService.findRuleGroupList(groupInfo);

        RuleGroupVO ruleGroupVO = new RuleGroupVO(ruleManage,insertList,ruleEntryList);
        return ruleGroupVO;
    }
}
